package com.kehutong.wwin.service.service;

import com.kehutong.common.errcode.Result;
import com.kehutong.common.util.Token;
import com.kehutong.wwin.service.entity.Corp;
import com.kehutong.wwin.service.entity.EmployeeMap;
import com.kehutong.wwin.service.entity.Suite;
import com.kehutong.wwin.service.util.WwInHttpClient;
import com.kehutong.wxapi.request.*;
import com.kehutong.wxapi.response.*;
import com.kehutong.wxapi.service.OauthService;
import com.kehutong.wxapi.service.UserService;
import org.coraframework.inject.Inject;
import org.coraframework.json.JSON;
import org.coraframework.json.JSONArray;
import org.coraframework.json.JSONObject;
import org.coraframework.mvc.http.ReqMapping;
import org.coraframework.mvc.webservice.WebService;
import org.coraframework.orm.jdbc.JdbcSession;

import java.util.Objects;

/**
 * 内建应用应用服务类
 *
 * @author: liukunlong
 * @date: 2021-03-30 19:51
 */
@WebService("/wwin-service/login")
public class LoginService {

    @Inject
    private WwInHttpClient httpClient;

    @Inject
    private JdbcSession jdbcSession;

    @Inject
    private OauthService oauthService;

    @Inject
    private CorpService corpService;

    @Inject
    private SuiteService suiteService;

    @Inject
    private UserService userService;

    @Inject
    private ToKhtEmployeeService toKhtEmployeeService;

    /**
     * 构建内建登录上下文信息
     *
     * @param token
     * @param wwJson
     * @return
     * @throws Exception
     */
    @ReqMapping("/buildWxInLoginContext")
    public Object buildWxInLoginContext(Token token, JSONObject wwJson) throws Exception {
        JSONObject result = new JSONObject();
        //微信企业编号
        String corpId = wwJson.getString("corpId");

        //通过成员授权获取到的code，最大为512字节。每次成员授权带上的code将不一样，code只能使用一次，5分钟未被使用自动过期。
        String code = wwJson.getString("code");
        Corp wwinCorp = corpService.getCorpById(corpId);
        if (Objects.isNull(wwinCorp)) {
            return Result.error(0, "微信内建企业不存在");
        }

        JSONObject corpResult = httpClient.postKht("/admin/service/corp/get", token, http -> {
            http.addParam("id", wwinCorp.getKhtid());
        });

        int corpResultCode = corpResult.getIntValue("code");
        if (corpResultCode != 200) {
            return Result.error(corpResultCode, corpResult.getString("message"));
        }
        JSONObject corp = corpResult.getJSONObject("data");
        if (Objects.isNull(corp)) {
            return Result.error(0, "客户通企业不存在");
        }

        //获取内建应用
        Suite site = jdbcSession.findOne(Suite.class)
                .eq("corpId", corpId)
                .exe();

        //切换相应企业数据库
        token.setCompanyNo(corp.getString("id"));

        //TODO 跟进内建应用标志获取内建应用token

        //获取访问用户身份
        GetUserInfoRequest getUserInfoRequest = new GetUserInfoRequest();
        //应用AccessToken(通过企业ID与应用的凭证密钥可以获得)
        getUserInfoRequest.setAccessToken(httpClient.getAppAccessToken(token));
        getUserInfoRequest.setCode(code);
        GetUserInfoResponse getUserInfoResponse = oauthService.getUserInfo(getUserInfoRequest);
        if (getUserInfoResponse.getErrcode() != 0) {
            return Result.error(getUserInfoResponse.getErrcode(), getUserInfoResponse.getErrmsg());
        }
        //访问用户的微信用户ID
        String userId = getUserInfoResponse.getUserId();

        //如果微信用户id不存在映射信息,则获取获取员工信息进行新增,然后返回员工信息
        EmployeeMap employeeMap = toKhtEmployeeService.getEmployeeByWwId(userId);
        if (Objects.isNull(employeeMap)) {
            UserGetRequest userGetRequest = new UserGetRequest();
            userGetRequest.setAccessToken(httpClient.getEmployeeAccessToken(token));
            userGetRequest.setUserid(userId);
            UserGetResponse userGetResponse = userService.userGet(userGetRequest);
            if (getUserInfoResponse.getErrcode() != 0) {
                return Result.error(getUserInfoResponse.getErrcode(), getUserInfoResponse.getErrmsg());
            }
            JSONObject wwinEmployeeJsonObject = new JSONObject();
            wwinEmployeeJsonObject.put("UserID", userGetResponse.getUserid());
            wwinEmployeeJsonObject.put("Name", userGetResponse.getName());
            wwinEmployeeJsonObject.put("Department", JSONArray.parseArray(JSON.toJSONString(userGetResponse.getDepartment())));
            wwinEmployeeJsonObject.put("MainDepartment", userGetResponse.getMainDepartment());
            wwinEmployeeJsonObject.put("Mobile", userGetResponse.getMobile());
            wwinEmployeeJsonObject.put("Gender", userGetResponse.getGender());
            wwinEmployeeJsonObject.put("Email", userGetResponse.getEmail());
            wwinEmployeeJsonObject.put("Avatar", userGetResponse.getAvatar());
            wwinEmployeeJsonObject.put("Telephone", userGetResponse.getTelephone());
            wwinEmployeeJsonObject.put("Address", userGetResponse.getAddress());
            EmployeeMap employeeMapObject = (EmployeeMap) toKhtEmployeeService.create(token, wwinEmployeeJsonObject);
            result.put("employee", employeeMapObject.toKhtJson());
            result.put("corp", corp);
            return result;
        }
        JSONObject employeeResult = httpClient.postKht("/employee/service/get", token, http -> {
            http.addParam("id", employeeMap.getKhtid());
        });

        int employeeResultCode = employeeResult.getIntValue("code");
        if (employeeResultCode != 200) {
            return Result.error(employeeResultCode, employeeResult.getString("message"));
        }
        JSONObject employee = employeeResult.getJSONObject("data");
        result.put("employee", employee);
        result.put("corp", corp);
        return result;
    }


    /**
     * 构建第三方登录上下文信息
     *
     * @param token
     * @param wwJson
     * @return
     * @throws Exception
     */
    @ReqMapping("/buildWxOutLoginContext")
    public Object buildWxOutLoginContext(Token token, JSONObject wwJson) throws Exception {
        JSONObject result = new JSONObject();
        String appId = wwJson.getString("appId");
        String code = wwJson.getString("code");

        //获取第三方应用
        Suite site = jdbcSession.findOne(Suite.class)
                .eq("appId", appId)
                .exe();

        GetUserInfo3rdRequest getUserInfo3rdRequest = new GetUserInfo3rdRequest();
        //TODO 第三方应用的suite_access_token，参见“获取第三方应用凭证”
        getUserInfo3rdRequest.setSuiteAccessToken("");
        getUserInfo3rdRequest.setCode(code);
        GetUserInfo3rdResponse getUserInfo3rdResponse = oauthService.getUserInfo3rd(getUserInfo3rdRequest);
        if (getUserInfo3rdResponse.getErrcode() != 0) {
            return Result.error(getUserInfo3rdResponse.getErrcode(), getUserInfo3rdResponse.getErrmsg());
        }


        Corp wwOutCorp = corpService.getCorpById(getUserInfo3rdResponse.getCorpId());
        if (Objects.isNull(wwOutCorp)) {
            return Result.error(0, "微信第三方企业不存在");
        }

        JSONObject corpResult = httpClient.postKht("/admin/service/corp/get", token, http -> {
            http.addParam("id", wwOutCorp.getKhtid());
        });

        int corpResultCode = corpResult.getIntValue("code");
        if (corpResultCode != 200) {
            return Result.error(corpResultCode, corpResult.getString("message"));
        }
        JSONObject corp = corpResult.getJSONObject("data");
        if (Objects.isNull(corp)) {
            return Result.error(0, "客户通企业不存在");
        }


        //切换相应企业数据库
        token.setCompanyNo(corp.getString("id"));
        //TODO 跟进内建应用标志获取内建应用token


        //访问用户的微信用户ID
        String userId = getUserInfo3rdResponse.getUserId();
        //如果微信用户id不存在映射信息,则获取获取员工信息进行新增,然后返回员工信息
        EmployeeMap employeeMap = toKhtEmployeeService.getEmployeeByWwId(userId);
        if (Objects.isNull(employeeMap)) {
            //获取访问用户敏感信息
            GetUserDetail3rdRequest getUserDetail3rdRequest = new GetUserDetail3rdRequest();
            //TODO 第三方应用的suite_access_token，参见“获取第三方应用凭证”
            getUserDetail3rdRequest.setSuiteAccessToken("");
            getUserDetail3rdRequest.setUserTicket(getUserInfo3rdResponse.getUserTicket());
            GetUserDetail3rdResponse getUserDetail3rdResponse = oauthService.getUserDetail3rd(getUserDetail3rdRequest);
            if (getUserDetail3rdResponse.getErrcode() != 0) {
                return Result.error(getUserDetail3rdResponse.getErrcode(), getUserDetail3rdResponse.getErrmsg());
            }
            JSONObject wwinEmployeeJsonObject = new JSONObject();
            wwinEmployeeJsonObject.put("UserID", getUserDetail3rdResponse.getUserid());
            wwinEmployeeJsonObject.put("Name", getUserDetail3rdResponse.getName());
            //wwinEmployeeJsonObject.put("Department", JSONArray.parseArray(JSON.toJSONString(getUserDetail3rdResponse.getDepartment())));
            // wwinEmployeeJsonObject.put("MainDepartment", userGetResponse.getMainDepartment());
            //wwinEmployeeJsonObject.put("Mobile", getUserDetail3rdResponse.getMobile());
            wwinEmployeeJsonObject.put("Gender", getUserDetail3rdResponse.getGender());
            //wwinEmployeeJsonObject.put("Email", userGetResponse.getEmail());
            wwinEmployeeJsonObject.put("Avatar", getUserDetail3rdResponse.getAvatar());
            //wwinEmployeeJsonObject.put("Telephone", userGetResponse.getTelephone());
            //wwinEmployeeJsonObject.put("Address", userGetResponse.getAddress());
            EmployeeMap employeeMapObject = (EmployeeMap) toKhtEmployeeService.create(token, wwinEmployeeJsonObject);
            result.put("employee", employeeMapObject.toKhtJson());
            result.put("corp", corp);
            return result;
        }
        JSONObject employeeResult = httpClient.postKht("/employee/service/get", token, http -> {
            http.addParam("id", employeeMap.getKhtid());
        });

        int employeeResultCode = employeeResult.getIntValue("code");
        if (employeeResultCode != 200) {
            return Result.error(employeeResultCode, employeeResult.getString("message"));
        }
        JSONObject employee = employeeResult.getJSONObject("data");
        result.put("employee", employee);
        result.put("corp", corp);
        return result;
    }


    /**
     * 构建内建扫码登录上下文信息
     *
     * @param token
     * @param wwJson
     * @return
     * @throws Exception
     */
    @ReqMapping("/buildQrcodeInLoginContext")
    public Object buildQrcodeInLoginContext(Token token, JSONObject wwJson) throws Exception {
        return buildWxInLoginContext(token,wwJson);
    }


    /**
     * 构建第三方扫码登录上下文信息
     *
     * @param token
     * @param wwJson
     * @return
     * @throws Exception
     */
    @ReqMapping("/buildQrcodeOutLoginContext")
    public Object buildQrcodeOutLoginContext(Token token, JSONObject wwJson) throws Exception {
        JSONObject result = new JSONObject();
        String authCode = wwJson.getString("authCode");

        GetLoginInfoRequest getLoginInfoRequest = new GetLoginInfoRequest();
        //授权登录服务商的网站时，使用应用提供商的provider_access_token，获取方法参见服务商的凭证
        getLoginInfoRequest.setAccessToken("");
        getLoginInfoRequest.setAuthCode(authCode);
        GetLoginInfoResponse getLoginInfoResponse = oauthService.getLoginInfo(getLoginInfoRequest);
        if (getLoginInfoResponse.getErrcode() != 0) {
            return Result.error(getLoginInfoResponse.getErrcode(), getLoginInfoResponse.getErrmsg());
        }
        GetLoginInfoResponse.UserInfoDTO userInfo = getLoginInfoResponse.getUserInfo();
        GetLoginInfoResponse.CorpInfoDTO corpInfo = getLoginInfoResponse.getCorpInfo();

        Corp wwOutCorp = corpService.getCorpById(corpInfo.getCorpid());
        if (Objects.isNull(wwOutCorp)) {
            return Result.error(0, "微信第三方企业不存在");
        }

        JSONObject corpResult = httpClient.postKht("/admin/service/corp/get", token, http -> {
            http.addParam("id", wwOutCorp.getKhtid());
        });

        int corpResultCode = corpResult.getIntValue("code");
        if (corpResultCode != 200) {
            return Result.error(corpResultCode, corpResult.getString("message"));
        }
        JSONObject corp = corpResult.getJSONObject("data");
        if (Objects.isNull(corp)) {
            return Result.error(0, "客户通企业不存在");
        }

        //切换相应企业数据库
        token.setCompanyNo(corp.getString("id"));
        //TODO 跟进内建应用标志获取内建应用token

        //访问用户的微信用户ID
        String userId = userInfo.getUserid();
        //如果微信用户id不存在映射信息,则获取获取员工信息进行新增,然后返回员工信息
        EmployeeMap employeeMap = toKhtEmployeeService.getEmployeeByWwId(userId);
        if (Objects.isNull(employeeMap)) {
            JSONObject wwoutEmployeeJsonObject = new JSONObject();
            wwoutEmployeeJsonObject.put("UserID", userInfo.getUserid());
            wwoutEmployeeJsonObject.put("Name", userInfo.getName());
            //wwinEmployeeJsonObject.put("Department", JSONArray.parseArray(JSON.toJSONString(getUserDetail3rdResponse.getDepartment())));
            // wwinEmployeeJsonObject.put("MainDepartment", userGetResponse.getMainDepartment());
            //wwinEmployeeJsonObject.put("Mobile", getUserDetail3rdResponse.getMobile());
            //wwoutEmployeeJsonObject.put("Gender", userInfo.getGender());
            //wwinEmployeeJsonObject.put("Email", userGetResponse.getEmail());
            wwoutEmployeeJsonObject.put("Avatar", userInfo.getAvatar());
            //wwinEmployeeJsonObject.put("Telephone", userGetResponse.getTelephone());
            //wwinEmployeeJsonObject.put("Address", userGetResponse.getAddress());
            EmployeeMap employeeMapObject = (EmployeeMap) toKhtEmployeeService.create(token, wwoutEmployeeJsonObject);
            result.put("employee", employeeMapObject.toKhtJson());
            result.put("corp", corp);
            return result;
        }
        JSONObject employeeResult = httpClient.postKht("/employee/service/get", token, http -> {
            http.addParam("id", employeeMap.getKhtid());
        });

        int employeeResultCode = employeeResult.getIntValue("code");
        if (employeeResultCode != 200) {
            return Result.error(employeeResultCode, employeeResult.getString("message"));
        }
        JSONObject employee = employeeResult.getJSONObject("data");
        result.put("employee", employee);
        result.put("corp", corp);
        return result;
    }
}
